home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xpaint-2.1.1 / Colormap.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  7KB  |  233 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. #include <math.h>
  16. #include <X11/IntrinsicP.h>
  17. #include <X11/Shell.h>
  18. #include <X11/StringDefs.h>
  19. #include "ColormapP.h"
  20.  
  21. static XtResource resources[] = {
  22. #define offset(field) XtOffset(ColormapWidget, color.field)
  23.     { XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
  24.       offset(callbacks), XtRCallback, (XtPointer)None },
  25.     { XtNcolor, XtCColor, XtRPixel, sizeof(Pixel),
  26.       offset(pixel), XtRImmediate, (XtPointer)None },
  27.     { XtNreadOnly, XtCReadOnly, XtRBoolean, sizeof(Boolean),
  28.       offset(editable), XtRImmediate, (XtPointer)False },
  29.     { XtNcellWidth, XtCCellWidth, XtRInt, sizeof(int),
  30.       offset(cwidth), XtRImmediate, (XtPointer)5 },
  31.     { XtNcellHeight, XtCCellHeight, XtRInt, sizeof(int),
  32.       offset(cheight), XtRImmediate, (XtPointer)5 },
  33.     { XtNthickness, XtCThickness, XtRInt, sizeof(int),
  34.       offset(thickness), XtRImmediate, (XtPointer)1 },
  35.     { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  36.       offset(foreground), XtRString, XtDefaultForeground },
  37. #undef offset
  38. };
  39.  
  40. static void ResizeProc(ColormapWidget);
  41. static void ExposeProc(ColormapWidget, XExposeEvent *);
  42. static void InitializeProc(ColormapWidget, ColormapWidget);
  43. static Boolean SetValuesProc(Widget, Widget, Widget);
  44.  
  45. static void drawSelection(ColormapWidget w, int flag)
  46. {
  47.     XGCValues    values;
  48.     int        x, y;
  49.     GC        gc;
  50.     int        t = w->color.thickness, t2 = t / 2 + 1;
  51.     
  52.     values.line_width = w->color.thickness;
  53.     if (flag) {
  54.         values.foreground = w->color.foreground;
  55.         values.background = w->core.background_pixel;
  56.     } else {
  57.         values.foreground = w->core.background_pixel;
  58.         values.background = w->color.foreground;
  59.     }
  60.  
  61.     gc = XtGetGC((Widget)w, GCForeground|GCBackground|GCLineWidth, &values);
  62.  
  63.     x = (w->color.pixel % w->color.ncwidth) * w->color.cwidth;
  64.     y = (w->color.pixel / w->color.ncwidth) * w->color.cheight;
  65.  
  66.     XDrawRectangle(XtDisplay(w), XtWindow(w), gc, 
  67.             x - t2, y - t2, w->color.cwidth, w->color.cheight);
  68. }
  69.  
  70. static void ColormapSelect(ColormapWidget w, XEvent* e, 
  71.                     String* str, Cardinal* n)
  72. {
  73.     int    pixel;
  74.     XColor    col;
  75.  
  76.     if ((e->xbutton.x / w->color.cwidth) > w->color.ncwidth)
  77.         return;
  78.     if ((e->xbutton.y / w->color.cheight) > w->color.ncheight)
  79.         return;
  80.  
  81.     
  82.     pixel = (e->xbutton.y / w->color.cheight) * w->color.ncwidth; 
  83.     pixel += e->xbutton.x / w->color.cwidth;
  84.  
  85.     drawSelection(w, FALSE);
  86.     w->color.pixel = pixel;
  87.     drawSelection(w, TRUE);
  88.  
  89.     col.pixel = pixel;
  90.     col.flags = DoRed|DoGreen|DoBlue;
  91.     XQueryColor(XtDisplay(w), w->core.colormap, &col);
  92.  
  93.     XtCallCallbackList((Widget)w, w->color.callbacks, (XtPointer)&col);
  94. }
  95.  
  96. static XtActionsRec actions[] =
  97. {
  98.   /* {name, procedure}, */
  99.     {"Set",    (XtActionProc)ColormapSelect},
  100. };
  101.  
  102. static char translations[] =
  103. "<BtnDown>:    Set()    \n\
  104. ";
  105.  
  106. ColormapClassRec colormapClassRec = {
  107.   { /* core fields */
  108.     /* superclass        */    (WidgetClass) &widgetClassRec,
  109.     /* class_name        */    "Colormap",
  110.     /* widget_size        */    sizeof(ColormapRec),
  111.     /* class_initialize        */    NULL,
  112.     /* class_part_initialize    */    NULL,
  113.     /* class_inited        */    FALSE,
  114.     /* initialize        */    (XtInitProc)InitializeProc,
  115.     /* initialize_hook        */    NULL,
  116.     /* realize            */    XtInheritRealize,
  117.     /* actions            */    actions,
  118.     /* num_actions        */    XtNumber(actions),
  119.     /* resources        */    resources,
  120.     /* num_resources        */    XtNumber(resources),
  121.     /* xrm_class        */    NULLQUARK,
  122.     /* compress_motion        */    TRUE,
  123.     /* compress_exposure    */    TRUE,
  124.     /* compress_enterleave    */    TRUE,
  125.     /* visible_interest        */    FALSE,
  126.     /* destroy            */    NULL,
  127.     /* resize            */    (XtWidgetProc)ResizeProc,
  128.     /* expose            */    (XtExposeProc)ExposeProc,
  129.     /* set_values        */    (XtSetValuesFunc)SetValuesProc,
  130.     /* set_values_hook        */    NULL,
  131.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  132.     /* get_values_hook        */    NULL,
  133.     /* accept_focus        */    NULL,
  134.     /* version            */    XtVersion,
  135.     /* callback_private        */    NULL,
  136.     /* tm_table            */    translations,
  137.     /* query_geometry        */    XtInheritQueryGeometry,
  138.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  139.     /* extension        */    NULL
  140.   },
  141.   { /* colormap fields */
  142.     /* empty            */    0
  143.   }
  144. };
  145.  
  146. WidgetClass colormapWidgetClass = (WidgetClass)&colormapClassRec;
  147.  
  148. static void InitializeProc(ColormapWidget w, ColormapWidget new)
  149. {
  150.     Widget    shell = XtParent(w);
  151.     Visual    *visual = NULL;
  152.  
  153.     while (!XtIsShell(shell))
  154.         shell = XtParent(shell);
  155.  
  156.     XtVaGetValues(shell, XtNvisual, &visual, NULL);
  157.     if (visual == NULL)
  158.         visual = DefaultVisualOfScreen(XtScreen(w));
  159.  
  160.     new->color.ncel     = visual->map_entries;
  161.     new->color.ncwidth  = (int)sqrt((double)new->color.ncel);
  162.     new->color.ncheight = (new->color.ncel + new->color.ncwidth - 1) /
  163.                     new->color.ncwidth;
  164.     if (new->core.width == 0) 
  165.         new->core.width  = new->color.cwidth * new->color.ncwidth;
  166.     else
  167.         new->color.cwidth = (int)new->core.width / (int)new->color.ncwidth;
  168.     if (new->core.height == 0) 
  169.         new->core.height  = new->color.cheight * new->color.ncheight;
  170.     else
  171.         new->color.cheight = new->core.height /  new->color.ncheight;
  172. }
  173.  
  174. static void ResizeProc(ColormapWidget w)
  175. {
  176.     w->color.cwidth  = w->core.width  /  w->color.ncwidth;
  177.     w->color.cheight = w->core.height /  w->color.ncheight;
  178. }
  179.  
  180. static void ExposeProc(ColormapWidget w, XExposeEvent *event)
  181. {
  182.     Display    *dpy = XtDisplay(w);
  183.     Window    win  = XtWindow(w);
  184.     GC    gc   = XCreateGC(dpy, win, 0, NULL);
  185.     int    color = 0;
  186.     int    x, y, X, Y;
  187.     int    nvert  = w->color.ncwidth;
  188.     int    nhoriz = w->color.ncheight;
  189.     int    t      = w->color.thickness;
  190.  
  191.     for (Y = y = 0; y < nhoriz; y++, Y += w->color.cheight) {
  192.         for (X = x = 0; x < nvert; x++, X += w->color.cwidth) {
  193.             XSetForeground(dpy, gc, color++);
  194.             XFillRectangle(dpy, win, gc, X, Y,
  195.                 w->color.cwidth - 1 - t, w->color.cheight - 1 - t);
  196.         }
  197.     }
  198.  
  199.     XFreeGC(dpy, gc);
  200.     drawSelection(w, TRUE);
  201. }
  202.  
  203. static Boolean SetValuesProc(Widget curArg, Widget request, Widget newArg)
  204. {
  205.     ColormapWidget    cur = (ColormapWidget)curArg;
  206.     ColormapWidget    new = (ColormapWidget)newArg;
  207.  
  208.     if (cur->color.pixel != new->color.pixel) {
  209.         drawSelection(cur, FALSE);
  210.         drawSelection(new, TRUE);
  211.     }
  212.  
  213.     return False;
  214. }
  215.  
  216.  
  217. void CwGetColor(Widget cw, XColor* col)
  218. {
  219.     ColormapWidget w = (ColormapWidget)cw;
  220.     
  221.     col->pixel = w->color.pixel;
  222.     col->flags = DoRed|DoGreen|DoBlue;
  223.     XQueryColor(XtDisplay(w), w->core.colormap, col);
  224. }
  225.  
  226. void CwSetColor(Widget cw, XColor* col)
  227. {
  228.     ColormapWidget w = (ColormapWidget)cw;
  229.     
  230.     col->pixel = w->color.pixel;
  231.     XStoreColor(XtDisplay(w), w->core.colormap, col);
  232. }
  233.